
`include "common_header.verilog"

//  *************************************************************************
//  File : block_decode_10l
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized Reproduction or Use is Expressly Prohibited. 
//  Copyright (c) 2001-2010 Morethanip
//  MorethanIP GmbH, GERMANY
//  info@morethanip.com
//  *************************************************************************
//  Version: $Id: block_decode_10l.v,v 1.1.1.1 2014/07/15 08:12:14 dk Exp $
//  Author : Serge Sciberras
//  Initial: 12/14/2001
//  *************************************************************************
// 
//  Description: 10G Base-R PCS RX: block decode function for rate adaptation
// 
//  *************************************************************************

module block_decode_10l (

   reset,
   sw_reset,
   ck_161,
   ck_ena,
   data_in,
   class_block,
   decode,
   error,
`ifdef MTIPPCS_EEE_ENA   
   lpi_seq_force,
`endif   
   rx_d_out,
   rx_c_out,
   rx_val);

input   reset;                  //  asynch reset
input   sw_reset;               //  synch reset
input   ck_161;                 //  system clock        
input   ck_ena;                 //  system clock        
input   [63:0] data_in;         //  data input
input   [3:0] class_block;      //  Class block
input   decode;                 //  decode can be done 
input   error;                  //  error should be sent --
`ifdef MTIPPCS_EEE_ENA 
input   lpi_seq_force;          //  when set, LPI is forced into the XGMII bus
`endif 
output  [63:0] rx_d_out;        //  Data out in XGMII format
output  [7:0] rx_c_out;         //  Control lane for XGMII format
output  rx_val;                 //  Data Valid

reg     [63:0]  rx_d_out;  
reg     [7:0]   rx_c_out;  
reg             rx_val; 
reg     [63:0]  data_arranged_a; //  data re-arranged
reg     [7:0]   control_lane_a; //  lane control 
reg     [1:0]   seq4_bit76; //  Bits 7..6 of sequence code in lane 4 (0x9c/0x5c)
reg     [1:0]   seq0_bit76; //  Bits 7..6 of sequence code in lane 4 (0x9c/0x5c)
reg     [7:0]   cd0; 
reg     [7:0]   cd1; 
reg     [7:0]   cd2; 
reg     [7:0]   cd3; 
reg     [7:0]   cd4; 
reg     [7:0]   cd5; 
reg     [7:0]   cd6; 
reg     [7:0]   cd7; 

// decode control codes to XGMII

function [7:0] C_DECODE;
input [6:0] c;
begin
        case ( c )
                7'b 0000000: C_DECODE = 8'h 07;
                `ifdef MTIPPCS_EEE_ENA
                7'b 0000110: C_DECODE = 8'h 06;
                `endif
                `ifdef ENA_CLAUSE49_RESERVED
                7'b 0101101: C_DECODE = 8'h 1c; // 2d: 1c
                7'b 0110011: C_DECODE = 8'h 3c; // 33: 3c
                7'b 1001011: C_DECODE = 8'h 7c; // 4b: 7c
                7'b 1010101: C_DECODE = 8'h bc; // 55: bc
                7'b 1100110: C_DECODE = 8'h dc; // 66: dc
                7'b 1111000: C_DECODE = 8'h f7; // 78: f7
                `endif
                default:     C_DECODE = 8'h FE; // all others including error: error
        endcase
end
endfunction

always @(data_in)
   begin : p_class_0
   if (data_in[32] == 1'b 1)
      begin
//  one bit of O-Code field is enough, as block_check will do the checking already
      seq0_bit76 = 2'b 01;	//  => 5c
      end
   else
      begin
      seq0_bit76 = 2'b 10;	//  MSBs of Sequence Code => 0x9c
      end
//  determine O(4)
   if (data_in[36] == 1'b 1)
      begin
//  one bit of O-Code field is enough, as block_check will do the checking already
      seq4_bit76 = 2'b 01;	//  => 5c
      end
   else
      begin
      seq4_bit76 = 2'b 10;	//  MSBs of Sequence Code => 0x9c
      end

//  --------------------
//  Decode Control codes
//  --------------------
   cd0 = C_DECODE(data_in[14:8]);	
   cd1 = C_DECODE(data_in[21:15]);	
   cd2 = C_DECODE(data_in[28:22]);	
   cd3 = C_DECODE(data_in[35:29]);	
   cd4 = C_DECODE(data_in[42:36]);	
   cd5 = C_DECODE(data_in[49:43]);	
   cd6 = C_DECODE(data_in[56:50]);	
   cd7 = C_DECODE(data_in[63:57]);	
   end

//  --------------------
//  Decode Sequence codes
//  --------------------
//  determine O(0)

always @(data_in or cd7 or cd6 or cd5 or cd4 or cd3 or cd2 or cd1 or cd0 or 
         class_block or seq4_bit76 or seq0_bit76)
   begin : p_class_1
   case (class_block)
   4'b 0000:
      begin
      data_arranged_a = data_in;	//  data code
      control_lane_a = 8'b 00000000;	
      end
   4'b 0001:
      begin
      data_arranged_a = {cd7, cd6, cd5, cd4, 
	cd3, cd2, cd1, cd0};	
      control_lane_a = 8'b 11111111;	
      end
   4'b 0010:
      begin
      data_arranged_a = {data_in[63:56], data_in[55:48], data_in[47:40], seq4_bit76[1:0], 
	6'b 011100, cd3, cd2, cd1, cd0};	                                //  Ordered code
      control_lane_a = 8'b 00011111;	
      end
   4'b 0011:
      begin
      data_arranged_a = {data_in[63:56], data_in[55:48], data_in[47:40], 8'b 11111011, cd3, cd2, cd1, cd0};	//  Start code lane 4
      control_lane_a = 8'b 00011111;	
      end
   4'b 0100:
      begin
      data_arranged_a = {data_in[63:56], data_in[55:48], data_in[47:40], 8'b 11111011, 
	data_in[31:24], data_in[23:16], data_in[15:8], seq0_bit76[1:0], 6'b 011100};    //  Start lane 4 and Ordered lane 0 code
      control_lane_a = 8'b 00010001;	
      end
   4'b 0101:
      begin
      data_arranged_a = {data_in[63:56], data_in[55:48], data_in[47:40], seq4_bit76[1:0], 
	6'b 011100, data_in[31:24], data_in[23:16], data_in[15:8], 
	seq0_bit76[1:0], 6'b 011100};	                                        //  two Ordered code lane 0 and 4
      control_lane_a = 8'b 00010001;	
      end
   4'b 0110:
      begin
      data_arranged_a = {data_in[63:8], 8'b 11111011};	                        //  Start code lane 0
      control_lane_a = 8'b 00000001;	
      end
   4'b 0111:
      begin
      data_arranged_a = {cd7, cd6, cd5, cd4, 
	data_in[31:24], data_in[23:16], data_in[15:8], seq0_bit76[1:0], 6'b 011100};	//  Ordered lane 0 code
      control_lane_a = 8'b 11110001;	
      end
   4'b 1000:
      begin
      data_arranged_a = {cd7, cd6, cd5, cd4, cd3, cd2, cd1, 8'b 11111101};	//  Terminate code lane 0
      control_lane_a = 8'b 11111111;	
      end
   4'b 1001:
      begin
      data_arranged_a = {cd7, cd6, cd5, cd4, 
	cd3, cd2, 8'b 11111101, data_in[15:8]};	                                //  Terminate code lane 1
      control_lane_a = 8'b 11111110;	
      end
   4'b 1010:
      begin
      data_arranged_a = {cd7, cd6, cd5, cd4, 
	cd3, 8'b 11111101, data_in[23:16], data_in[15:8]};	                //  Terminate code lane 2
      control_lane_a = 8'b 11111100;	
      end
   4'b 1011:
      begin
      data_arranged_a = {cd7, cd6, cd5, cd4, 
	8'b 11111101, data_in[31:24], data_in[23:16], data_in[15:8]};	        //  Terminate code lane 3
      control_lane_a = 8'b 11111000;	
      end
   4'b 1100:
      begin
      data_arranged_a = {cd7, cd6, cd5, 8'b 11111101, 
	data_in[39:32], data_in[31:24], data_in[23:16], data_in[15:8]};	        //  Terminate code lane 4
      control_lane_a = 8'b 11110000;	
      end
   4'b 1101:
      begin
      data_arranged_a = {cd7, cd6, 8'b 11111101, data_in[47:40], 
	data_in[39:32], data_in[31:24], data_in[23:16], data_in[15:8]};	        //  Terminate code lane 5
      control_lane_a = 8'b 11100000;	
      end
   4'b 1110:
      begin
      data_arranged_a = {cd7, 8'b 11111101, data_in[55:48], data_in[47:40], 
	data_in[39:32], data_in[31:24], data_in[23:16], data_in[15:8]};	        //  Terminate code lane 6
      control_lane_a = 8'b 11000000;	
      end
   4'b 1111:
      begin
      data_arranged_a = {8'b 11111101, data_in[63:56], data_in[55:48], data_in[47:40], 
	data_in[39:32], data_in[31:24], data_in[23:16], data_in[15:8]};	        //  Terminate code lane 7
      control_lane_a = 8'b 10000000;	
      end
   default:
      begin
      data_arranged_a = data_in;	
      control_lane_a = 8'b 00000000;	
      end
   endcase
   end


// ------------------------------
// =====================================================================
//  FINAL MUX
// =====================================================================
always @(posedge ck_161 or posedge reset)
   begin : p_final
   if (reset == 1'b 1)
      begin          
      rx_d_out <= {64{1'b 0}};	
      rx_c_out <= {8{1'b 0}};	
      end
   else if (ck_ena == 1'b 1)
      begin
// -----------------------------
//  Final mux for XGMII format
// -----------------------------    
`ifdef MTIPPCS_EEE_ENA
      if (lpi_seq_force == 1'b1)
        begin
        rx_d_out <= 64'h 06060606_06060606;	//  Force Lpi
        rx_c_out <= 8'h FF;                
        end
      else
`endif   
      if (decode == 1'b 0)
         begin
         rx_d_out <= 64'b 0000000100000000000000001001110000000001000000000000000010011100;	//  2 Local fault
         rx_c_out <= 8'b 00010001;	
         end
      else if (error == 1'b 1 )
         begin
         rx_d_out <= 64'b 1111111011111110111111101111111011111110111111101111111011111110;	//  Error FE every where
         rx_c_out <= 8'b 11111111;	
         end
      else
         begin
         rx_d_out <= data_arranged_a;	// normal data
         rx_c_out <= control_lane_a;	
         end
      end
   end


always @(posedge ck_161 or posedge reset)
begin
   if (reset == 1'b 1)
      begin
      rx_val <= 1'b 0;	//  XGMII data valide            
      end
   else
      begin
      if (sw_reset==1'b1)
         begin
           rx_val <= 1'b 0;	//  XGMII data valide 
         end
      else
         begin
        // -----------------------------
        //  Block type received valide
        // ----------------------------- 
         rx_val <= ck_ena;             //  FIFO Enable
         end
     end
end


endmodule // module block_decode_10l
